/****************************************************************************
*                                                                           *
* repository.h -- template singleton implementation of repository           *
*                                                                           *
* ALaRI 2008												                *
*                                                                           *
****************************************************************************/
#pragma once

#if !defined(__REPOSITORY_H)
#define __REPOSITORY_H

#include "defs.h"
#include "singleton.h"
#include <map>
#include <list>

template <class _I, typename _T_Id, typename _T_Item> 
class CRepository : public CSingleton<_I>
{
	friend class CSingleton<_I>;

public : 
	/****************************************************************************
	* Public interface															*
	****************************************************************************/
	virtual void init() = 0; 
	virtual void destroy() { CSingleton<_I>::destroyInstance(); }
	bool isEmpty() { return m_mapItems.empty(); }
	int	count()	{ return m_mapItems.size(); }

protected:
	/****************************************************************************
	* Protected																	*
	****************************************************************************/
	typedef typename std::map<_T_Id, _T_Item>::const_iterator const_iterator;
	typedef typename std::map<_T_Id, _T_Item>::iterator iterator;
	std::list<_T_Item> toList() const;
	_T_Item getItem(_T_Id itemID) const; 
	void addItem(_T_Id itemID, _T_Item item);
	void removeItem(_T_Id itemID);
	void clear();
	iterator end() { return m_mapItems.end(); } 
	iterator begin() { return m_mapItems.begin(); } 

	/****************************************************************************
	* Protected	construction/destruction										*
	****************************************************************************/
	CRepository() 
	{}
	~CRepository();

private : 
	/****************************************************************************
	* Private data																*
	****************************************************************************/
	std::map<_T_Id, _T_Item> m_mapItems;
};

template <class _I, typename _T_Id, typename _T_Item> 
void CRepository<_I, _T_Id, _T_Item>::addItem(_T_Id itemID, _T_Item item)
{
	// delete item if it is already present
	iterator it = m_mapItems.find(itemID);
	if (it != m_mapItems.end())
	{
		SafeFree((*it).second);
		m_mapItems.erase(it);
	}
	//save new item properties
	m_mapItems[itemID] = item;	
}

template <class _I, typename _T_Id, typename _T_Item> 
_T_Item CRepository<_I, _T_Id, _T_Item>::getItem(_T_Id itemID) const 
{
	const_iterator it = m_mapItems.find(itemID);
	if (it == m_mapItems.end())
		return NULL;
	return ((*it).second);
}

template <class _I, typename _T_Id, typename _T_Item> 
void CRepository<_I, _T_Id, _T_Item>::removeItem(_T_Id itemID)
{
	iterator it = m_mapItems.find(itemID);
	if (it != m_mapItems.end())
	{
		SafeFree((*it).second);
		m_mapItems.erase(it);
	}
}

template <class _I, typename _T_Id, typename _T_Item> 
std::list<_T_Item> CRepository<_I, _T_Id, _T_Item>::toList() const 
{
	std::list<_T_Item> listItems;
	const_iterator it = m_mapItems.begin();
	while (it != m_mapItems.end())
	{
		listItems.push_back((*it).second);
		*it++;
	}
	return listItems;
}

template <class _I, typename _T_Id, typename _T_Item> 
CRepository<_I, _T_Id, _T_Item>::~CRepository()
{
	clear();
}

template <class _I, typename _T_Id, typename _T_Item> 
void CRepository<_I, _T_Id, _T_Item>::clear()
{
	iterator it;
	for (it = m_mapItems.begin(); it != m_mapItems.end(); it++ )
		SafeFree((*it).second);
	m_mapItems.clear();
}

#endif /* __SINGLETON_H */
/****************************************************************************
* End of file																*
****************************************************************************/
